import {
  useImperativeHandle,
  useCallback,
  ReactElement,
  useState,
  useEffect,
  Ref,
  useMemo,
} from 'react';
import { Checkbox, Radio, Popup, CheckList } from 'antd-mobile';
import EformSelectList from '../../designer/wapServer/EformSelectList';
import EformSelectInput from '../../designer/wapServer/EformSelectInput';
import { multilingualFormat, useEvents } from '@inbiz/utils';
import api from './api';
import './index.less';
import { getMessage, TextWidget } from '@inbiz/react';
import { observer } from '@formily/react';
import { GlobalRegistry } from '@inbiz/core';
import {
  IBaseEformStaticList,
  defaultValueFormat,
  useRequestData,
  originValueFormat,
} from '../public';

type Iprops = IBaseEformStaticList & {
  viewMode?: string;
  emit?: {
    /** 内容改变时触发 */
    (type: 'onChange', value: any): void;
    /**下拉模式下 弹出框选中项触发 */
    (type: 'onSelect', value?: string): void;
    (type: 'onLoad'): void;
    (type: 'onSuccess', arg: object[]): void;
    (type: 'onError'): void;
  };
  ref: ref
};

type ref = Ref<ReturnType<typeof api>>;
const EformStaticList = observer((props: Iprops): ReactElement => {
  const ref = props.ref;
  const [events] = useEvents(props.callBackEvents, props.emit);
  const [state, $state] = useState<any>({
    ...props,
    value: [],
    checkList: '',
    autoLoading: props.autoLoading == undefined ? true : props.autoLoading,
  });

  const {
    value,
    labelDirection,
    // defaultValue,
    checkList, //下拉列表选择项
    // required,
    selectWindowHeight, //弹框高度
    autoLoading, //自动加载
  } = state;

  const {
    readOnly, // 只读
    showMode, //显示模式    1平铺            2下拉
    selectMode, //选择方式    flse单选    true多选
    layoutMode, //排列方式    portrait纵向        transverse横向
    viewMode
  } = props;

  const { data, mutate: $dataList, runAsync, loading } = useRequestData(props, events);

  const dataList = useMemo(() => {
    if (data) {
      return data.map(item => ({...item, label: multilingualFormat(item.label)}))
    } else {
      return []
    }
  }, [data, GlobalRegistry.getDesignerLanguage()]);

  // 请求数据源
  const getData = useCallback(
    (isFirst = false) => {
      const data = { appId } as { key?: string; appId: string; groupKey?: string };
      if (typeof props.dataGroupId == 'object') {
        const modelKey = props.dataGroupId?.['modelKey'];
        if (modelKey) {
          data.key = modelKey;
        }
      } else {
        data.groupKey = props.dataGroupId;
      }
      if (!props.dataGroupId) {
        return;
      }
      if (!props.dataGroupId && !events.current.onRequest) {
        return;
      }
      return runAsync(data).then(
        (res) => {
          props.emit?.('onSuccess', res as []);
          if (isFirst) {
            props.emit?.('onLoad');
          }
        },
        (e) => {
          props.emit?.('onError');
        },
      );
    },
    [runAsync, props.dataGroupId, props.emit],
  );

  const [valueJson, $valueJson] = useState<any[]>([]);

  const appId = props.inbiz.appInfo.appId;

  useEffect(() => {
    if (
      props.value === undefined &&
      (!(autoLoading == undefined || autoLoading) || showMode == 2 || (!props.dataGroupId && !events.current.onRequest))
    ) {
      props.emit?.('onLoad');
      return;
    }
    getData(true);
  }, [props.dataGroupId, autoLoading]);

  const [popupVisible, $popupVisible] = useState(false);
  const [clickNum, $clickNum] = useState(0);
  const [text, $text] = useState('');
  useEffect(() => {
    $text(ref?.current?.getText?.() || '')
  }, [value])

  //筛选默认值 当没有返回默认值的时候 清空该默认值 || 处理表格详情页的值
  useEffect(() => {
    if (props.value === undefined || props.value.length == 0) {
      let values = selectMode ? [] : '';
      $state({ ...state, value: values, checkList: [] });
      $valueJson([]);
      return;
    }
    if (dataList.length > 0 && props.value) {
      if (!selectMode) {
        let newValue: any = {};
        if (props.value && props.value.toString()?.indexOf(',') != -1) return;
        dataList.forEach((item: any) => {
          if (item.value == props.value) {
            newValue = item;
          }
        });
        let arr: any[] = [];
        dataList.map((item: any) => {
          if (newValue.value === item.value) {
            arr.push(JSON.stringify(item));
          }
        });
        $state((state: any) => ({ ...state, value: newValue.value, checkList: [newValue.value] }));
        if (Array.isArray(props.value)) {
          props.value[0] !== newValue.value && props.onChange?.(newValue.value);
        } else {
          props.value !== newValue.value && props.onChange?.(newValue.value);
        }
        $valueJson(arr);
        $itemChange([props.value])
      } else {
        let defaultValueArry: any = [];
        if (props.value && props.value.toString()?.indexOf(',') != -1) {
          if (typeof props.value === 'string') {
            defaultValueArry = props.value.split(',');
          } else {
            defaultValueArry = props.value;
          }
        } else {
          defaultValueArry = Array.isArray(props.value) ? props.value : [props.value];
        }
        let newValue: string[] = [];
        defaultValueArry.forEach((item: any) => {
          dataList.forEach((item1: any) => {
            if (item == item1.value) newValue.push(item1.value);
          });
        });
        newValue = [...new Set(newValue)];
        let arr: any[] = [];
        dataList.map((item: any) => {
          if (newValue.includes(item.value)) {
            arr.push(JSON.stringify(item));
          }
        });
        $state((state: any) => ({ ...state, value: newValue, checkList: newValue }));
        props.value.toString() !== newValue.toString() && props.onChange?.(newValue);
        $valueJson(arr);
        $itemChange(props.value);
      }
    }
    if (dataList.length === 0 && props.value && !loading) {
      getData()
    }
  }, [dataList, props.value, props.defaultValue]);

  const handleChange = useCallback(
    (value) => {
      let data = { ...state, value };
      $state(data);
      props.onChange?.(value);
    },
    [state, props.onChange],
  );
  useImperativeHandle(
    ref,
    () => {
      return {
        ...api(events, {
          state,
          dataList,
          $dataList,
          props,
        }),
      };
    },
    [state, props, dataList],
  );

  /*--------------------------------------------------向外暴露的方法-setValue(end)------------------------------------ */
  // 单选框
  let EformRadio = () => {
    let newOptions = props.hideDisabledOptions
      ? dataList?.filter((item: any) => props.disabledOptions?.indexOf(item.value) === -1)
      : dataList;
    return (
      //@ts-ignore
      <Radio.Group
        value={value || props.defaultValue}
        onChange={handleChange}
        disabled={props.readOnly}
      >
        {newOptions.length > 0 &&
          newOptions.map((item, index: number) => {
            return (
              <Radio
                value={item.value}
                disabled={
                  item.disabled ?? props.disabledOptions
                    ? props.disabledOptions?.indexOf(item.value?.toString()) != -1
                      ? true
                      : false
                    : false
                }
                block={layoutMode == 'portrait' ? true : false}
                className="radio-check-item"
                key={index}
                style={{ wordBreak: 'break-all' }}
              >
                <TextWidget>{item.label ?? item['text']}</TextWidget>
              </Radio>
            );
          })}
      </Radio.Group>
    );
  };
  // 多选框
  let EformCheckBox = () => {
    let newOptions = props.hideDisabledOptions
      ? dataList?.filter((item: any) => props.disabledOptions?.indexOf(item.value) === -1)
      : dataList;
    return (
      //@ts-ignore
      <Checkbox.Group value={value} onChange={handleChange} disabled={props.readOnly}>
        {newOptions.length > 0 &&
          newOptions.map((item, index: number) => {
            return (
              <Checkbox
                value={item.value}
                disabled={
                  item.disabled ?? props.disabledOptions
                    ? props.disabledOptions?.indexOf(item.value?.toString()) != -1
                      ? true
                      : false
                    : false
                }
                block={layoutMode == 'portrait' ? true : false}
                className="checkbox-check-item"
                key={index}
                style={{ wordBreak: 'break-all' }}
              >
                <TextWidget>{item.label ?? item['text']}</TextWidget>
              </Checkbox>
            );
          })}
      </Checkbox.Group>
    );
  };
  // popup层列表
  const [itemChange, $itemChange] = useState<any[]>([]);

  
  const EformCheckList = ({ numberChange }: { numberChange: (n: number) => void }) => {
    let newOptions = props.hideDisabledOptions
      ? dataList?.filter((item) => props.disabledOptions?.indexOf(item.value?.toString()) === -1)
      : dataList;
    return (
      <CheckList
        active-background-color="#333"
        multiple={!selectMode && showMode == 2 ? false : true}
        // defaultValue={state.value}
        value={itemChange}
        onChange={(val: string[]) => {
          numberChange(val.length);
          $itemChange(val)
          // $state({ ...state, checkList: val });
          //@ts-ignore
          props.emit?.('onSelect', val);
        }}
      >
        {newOptions.length > 0 &&
          newOptions.map((item, index: number) => {
            return (
              <CheckList.Item
                value={item.value?.toString()}
                key={index}
                disabled={
                  item.disabled ?? props.disabledOptions
                    ? props.disabledOptions?.indexOf(item.value?.toString()) != -1
                      ? true
                      : false
                    : false
                }
              >
                <TextWidget>{item.label ?? item['text']}</TextWidget>
              </CheckList.Item>
            );
          })}
      </CheckList>
    );
  };
  // tags的移除事件
  const remove = (e: any, item: any) => {
    e.stopPropagation();
    if (!selectMode) {
      $state({ ...state, value: [], checkList: [] });
      props.onChange?.('');
      $itemChange([]);
    } else {
      let newValue: string[];
      newValue = state.value.filter((valueItem: any) => valueItem != item.value);
      $state({ ...state, value: newValue, checkList: newValue });
      $itemChange(newValue);
      props.onChange?.(newValue);
    }
  };

  // 打开popup层选择
  const openPopup = useCallback(() => {
    if (showMode == 2 && !readOnly && !props.inbiz.browser.designer) {
      $popupVisible(true);
      if (clickNum == 0 && autoLoading) {
        getData();
        $clickNum(1);
      }
    }
  }, [showMode, readOnly, clickNum, autoLoading, props.inbiz.browser.designer]);

  // 取消选中值
  const cancelSelect = ()=> {
    $popupVisible(false)
    if (typeof state.value == 'string') {
      $itemChange([state.value])
    } else {
      $itemChange(state.value)
    }
  }
  return (
    <>
      {viewMode == 'look' ? <div style={{lineHeight:'31.5px',fontSize:'16px'}}>{text}</div> :
        <>
          <div className="EformStaticListContent">
            {!selectMode && showMode == 1 ? (
              <EformRadio />
            ) : selectMode && showMode == 1 ? (
              <EformCheckBox />
            ) : (
              <EformSelectInput
                labelDirection={labelDirection}
                selectMode={selectMode!}
                value={valueJson}
                readonly={readOnly || state.disabled}
                placeholder={state.placeholder ? getMessage(state.placeholder) : ''}
                remove={remove}
                type="staticList"
                showField="label"
                saveField="value"
                open={openPopup}
              />
            )}
          </div>
          <Popup
            getContainer={() => document.querySelector('.rootContainer') || document.body}
            position="bottom"
            onMaskClick={cancelSelect}
            visible={popupVisible}
            bodyStyle={{
              height: selectWindowHeight ? selectWindowHeight + '%' : '',
              borderTopLeftRadius: 8,
              borderTopRightRadius: 8,
              overflow: 'hidden',
            }}
            destroyOnClose
          >
            <EformSelectList
              selectWindowHeight={selectWindowHeight}
              contentHeight={'74%'}
              type={selectMode!}
              confirm={() => {
                $popupVisible(false);
                let values = [...itemChange];
                let arr: any[] = [];
                values.map((item) => {
                  dataList.map((val: any) => {
                    if (val.value === item) {
                      arr.push(JSON.stringify(val));
                    }
                  });
                });
                $state({ ...state, value: values });
                // $itemChange([])
                $valueJson(arr);
                props.onChange?.(selectMode ? values : values[0]);
              }}
              cancel={cancelSelect}
              children={(numberChange: any) => <EformCheckList numberChange={numberChange} />}
              value={value}
            />
          </Popup>
        </>
      }
    </>
  );
}, {
  forwardRef: true
});
EformStaticList.displayName = 'EformStaticList';

EformStaticList['defaultValueFormat'] = defaultValueFormat;
EformStaticList['originValueFormat'] = originValueFormat;

export default EformStaticList;
